package com.fadadianqi.logistics.admin.ticket.service;

import com.fadadianqi.logistics.admin.ticket.dao.WinnerDAO;
import com.fadadianqi.logistics.admin.ticket.model.Prize;
import com.fadadianqi.logistics.admin.ticket.model.Winner;
import com.fadadianqi.commons.ConfigHelper;
import com.fadadianqi.commons.JSONProvider;
import com.fadadianqi.commons.PrimaryKeyCreator;
import com.fadadianqi.logistics.sell.model.Bill;
import com.fadadianqi.logistics.sell.service.BillService;
import com.yeqiangwei.commons.util.ArithHelper;
import com.yeqiangwei.commons.util.Utils;
import com.yeqiangwei.commons.util.ValidatorHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class LotteryDrawService {

    private static final Log log = LogFactory.getLog(LotteryDrawService.class);

    /**
     * 抽奖
     *
     * @param bill
     */
    public Prize lotteryDraw(Bill bill) {
        Prize prize = null;
        /*抽奖次数*/
        Integer drawNumber = getDrawNumber(bill);
		
		/*最多获奖次数*/
        Double _winMax = ArithHelper.mul(new Double(String.valueOf(drawNumber)), getBillProbability());
        int winMax = _winMax.intValue(); //

        log.info("drawNumber： " + drawNumber + ", winMax： " + winMax);

        if (winMax == countWinnerByBillId(bill)) {
            // 如果中奖次数达到上限
            return null;
        }
		/*
		 * 如果没有达到获奖次数上限 
		 */
		
		/*所有奖品*/
        List<Prize> allPrize = getPrizePool(bill);
        if (ValidatorHelper.isEmpty(allPrize)) {
            // 没有奖品了获取纪念奖
        }
		/*奖品总数*/
        int prizeTotal = allPrize.size();
		/*奖品总数除以中奖概率=彩票总数*/
        int num = div(prizeTotal, getPrizeProbability(), 0).intValue();
		/*执行抽奖*/
        Long r = Utils.getRandomNumber(0, num);
        if (r.intValue() < allPrize.size()) {
            prize = allPrize.get(r.intValue());
            // 中奖啦
            /**
             * TODO 中奖之后好多事情要做
             * 保存获奖记录
             * 抽奖次数将减少一次
             */
            saveWinner(bill, prize);
            prize.setCount(prize.getCount() - 1);
            prizeService.save(prize);
        }
        return prize;
    }

    public int getDrawNumber(Bill bill) {
		/*每多少钱一次*/
        Double money = new Double(ConfigHelper.getString("admin.ticket.money", "100"));
		/*抽奖次数*/
        return new Double(div(bill.getRealPayables(), money, 0)).intValue();
    }

    public int countWinnerByBillId(Bill bill) {
        return winnerDAO.countWinnerByBillId(bill.getId());
    }

    /**
     * 所有奖品组成奖品池的中奖概率
     */
    private Double getPrizeProbability() {
        return new Double(ConfigHelper.getString("admin.ticket.prize.probability", "0.9"));
    }

    /**
     * 每张订单的最高中奖概率
     *
     * @return
     */
    private Double getBillProbability() {
        return new Double(ConfigHelper.getString("admin.ticket.bill.probability", "0.5"));
    }

    /**
     * 所有待抽取的奖品总数
     *
     * @param bill
     * @return
     */
    private List<Prize> getPrizePool(Bill bill) {
        int drawNumber = getDrawNumber(bill);
        List<Prize> prizePool = new ArrayList<Prize>(drawNumber);
		
		/*可以抽取的奖品类型*/
        List<Prize> prizeItems = getNormalPrizeItems(bill);
        for (Prize prize : prizeItems) {
            for (int i = 1; i <= prize.getCount(); i++) {
                prizePool.add(prize);
            }
        }
        return prizePool;
    }

    /**
     * 获取普通奖奖品
     *
     * @param bill
     * @return
     */
    private List<Prize> getNormalPrizeItems(Bill bill) {
		/*中奖概率
		Double probably = new Double(ConfigHelper.getString("admin.ticket.probably", "50"));
		
		订单利润
		Double profit = ArithHelper.sub(bill.getRealPayables(), bill.getCost());
		
		#奖品占利润的百分比
		Double percent = new Double(ConfigHelper.getString("admin.ticket.prize.bill.profit.percent", "0"));
		
		奖品成本
		Double prizeCost = ArithHelper.mul(profit, percent);
		
		log.info(profit + " * " + percent + " = " + prizeCost);*/
		
		/*按利润百分比中奖的奖品*/
        List<Prize> list1 = prizeService.findByTypeAndNotWithdraw(Prize.TYPE_PROFIX_PERCENT);
        List<Prize> list2 = prizeService.findByTypeAndNotWithdraw(Prize.TYPE_RANDOM);
        List<Prize> list = new ArrayList<Prize>();
        list.addAll(list1);
        list.addAll(list2);
        return list;
    }


    /**
     * 四舍五不入
     *
     * @param v1
     * @param v2
     * @param scale
     * @return
     */
    private Double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        if (v2 == 0) {
            return 0D;
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
    }

    private void saveWinner(Bill bill, Prize prize) {
        Winner winner = new Winner();
        winner.setAddTime(new Date());
        winner.setId(PrimaryKeyCreator.create());
        winner.setBillId(bill.getId());
        winner.setCustomerId(bill.getCustomerId());
        winner.setCost(prize.getCost());
        winner.setValue(prize.getValue());
        winner.setPrizeJSON(JSONProvider.toJSON(prize));
        winnerDAO.create(winner);
    }

    @Autowired
    private WinnerDAO winnerDAO;

    @Autowired
    private BillService billService;

    @Autowired
    private PrizeService prizeService;
}
